package org.qs.webservice.util;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Random;
import java.util.TreeMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;













import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;

import org.apache.log4j.Logger;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.ser.CustomSerializerFactory;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.qs.webservice.content.IReadContent;
import org.qs.webservice.dao.user.UserGradeMapper;
import org.qs.webservice.domain.ConChapter;
import org.qs.webservice.domain.UsUser;
import org.qs.webservice.domain.UserGrade;
import org.qs.webservice.service.IreadMemcacheService;
import org.qs.webservice.sign.DESCoder;
/**
 * 操作类
 * @ClassName: IReadUtils 
 * @author xusaike 
 * @date 2015年9月24日 下午12:58:13 
 *
 */
public class IReadUtils {
	private static final Logger logger = Logger.getLogger(IReadUtils.class.getName());
	
	public static String getUserLevel(IreadMemcacheService ireadMemcacheService,Long point,UserGradeMapper userGradeMapper){
		String key = "qs_read_user_level";
		String str = (String) ireadMemcacheService.get(key);
		if(str==null){
			List<UserGrade> list = userGradeMapper.getUserGradeList();
			if(list!=null){
				ireadMemcacheService.set(key, IReadContent.user_level_effective_time, IReadUtils.beanToJson(list));
				String level = list.get(0).getGrade_name();
				for(UserGrade userGrade :list){
					if(point==null){
						point = (long) IReadContent.base_point;
					}
					if(userGrade.getGrade_value()>point){
						break;
					}
					level = userGrade.getGrade_name();
				
				}
				return level;
			}
		}else{
			JSONArray jsonArray = JSONArray.fromObject(str);
			List<UserGrade> userGrades=(List<UserGrade>) JSONArray.toList(jsonArray, UserGrade.class); 
			if(userGrades.size()>0){
				String level = userGrades.get(0).getGrade_name();
				for(UserGrade userGrade :userGrades){
					if(userGrade!=null){
						if(point==null){
							point = (long) IReadContent.base_point;
						}
						if(userGrade.getGrade_value()>point){
							break;
						}
						level = userGrade.getGrade_name();
					}
				}
				return level;
			}
		
		}
		return "未知";
	}
	public static int getChapterFeeByUser(IreadMemcacheService ireadMemcacheService,Long point,UserGradeMapper userGradeMapper,int wordSize,ConChapter conChapter){
		int totalVotes = 1;
		String key = "qs_read_user_level";
		String str = (String) ireadMemcacheService.get(key);
		if(str==null){
			List<UserGrade> list = userGradeMapper.getUserGradeList();
			if(list!=null){
				ireadMemcacheService.set(key, IReadContent.user_level_effective_time, IReadUtils.beanToJson(list));
				int level = list.get(0).getGrade_id();
				for(UserGrade userGrade :list){
					if(point==null){
						point = (long) IReadContent.base_point;
					}
					if(userGrade.getGrade_value()>point){
						break;
					}
					level = userGrade.getGrade_id();
				
				}
				totalVotes = level;
			}
		}else{
			JSONArray jsonArray = JSONArray.fromObject(str);
			List<UserGrade> userGrades=(List<UserGrade>) JSONArray.toList(jsonArray, UserGrade.class); 
			if(userGrades.size()>0){
				int level = userGrades.get(0).getGrade_id();
				for(UserGrade userGrade :userGrades){
					if(userGrade!=null){
						if(point==null){
							point = (long) IReadContent.base_point;
						}
						if(userGrade.getGrade_value()>point){
							break;
						}
						level = userGrade.getGrade_id();
					}
				}
				totalVotes = level;
			}
		
		}
		if(conChapter.getBook_vip_status()==2){
			int chapterFee = conChapter.getBook_price();
			if(totalVotes>=5){
				chapterFee= (int)(conChapter.getBook_price()*0.75);
			}
			if(totalVotes>=9){
				chapterFee=   (int)(conChapter.getBook_price()*0.5);
			}
			return chapterFee;
		}else{
			int chapterFee = wordSize*IReadContent.original_chapter_price/1000;
			if(totalVotes>=5){
				chapterFee= wordSize*IReadContent.unior_member_chapter_price/1000;
			}
			if(totalVotes>=9){
				chapterFee= wordSize*IReadContent.senior_member_chapter_price/1000;
			}
			return chapterFee;
		}
		
	}
	public static int getTotalVotes(Long point,IreadMemcacheService ireadMemcacheService,UserGradeMapper userGradeMapper){
		int totalVotes = 1;
		String key = "qs_read_user_level";
		String str = (String) ireadMemcacheService.get(key);
		if(str==null){
			List<UserGrade> list = userGradeMapper.getUserGradeList();
			if(list!=null){
				ireadMemcacheService.set(key, IReadContent.user_level_effective_time, IReadUtils.beanToJson(list));
				int level = list.get(0).getGrade_id();
				for(UserGrade userGrade :list){
					if(point==null){
						point = (long) IReadContent.base_point;
					}
					if(userGrade.getGrade_value()>point){
						break;
					}
					level = userGrade.getGrade_id();
				
				}
				totalVotes = level;
			}
		}else{
			JSONArray jsonArray = JSONArray.fromObject(str);
			List<UserGrade> userGrades=(List<UserGrade>) JSONArray.toList(jsonArray, UserGrade.class); 
			if(userGrades.size()>0){
				int level = userGrades.get(0).getGrade_id();
				for(UserGrade userGrade :userGrades){
					if(userGrade!=null){
						if(point==null){
							point = (long) IReadContent.base_point;
						}
						if(userGrade.getGrade_value()>point){
							break;
						}
						level = userGrade.getGrade_id();
					}
				}
				totalVotes = level;
			}
		
		}
		return totalVotes*2;
		
		
		
		/*int totalVotes = 2;
		if(usUser.getBalance()>5000){
			totalVotes= 10;
		}else if(usUser.getBalance()>2000){
			totalVotes= 5;
		}
		return totalVotes;*/
	}
	
	/**
	 * 获取token中的userid，不判断是否有效
	 * @Title: getUserIdByToken 
	 * @param token
	 * @param ireadMemcacheService
	 * @return   
	 * @return String    
	 * @throws
	 */
	public static String getUserIdByTokenWithoutEffective(String token){
		try {
			if(!StringUtils.isNullOrEmpty(token)){
				token=URLDecoder.decode(token,"UTF-8");
				byte[] strn=DESCoder.decrypt(DESCoder.decryptBASE64(token), IReadContent.dec_password);
				String key = new String(strn);
				String userId=key.split(":")[0];
				return userId;
			}
		} catch (Exception e) {
			logger.error("token error");
			logger.error(token);
			e.printStackTrace();
		}
		return "";
	}
	public static String getUserIdByToken(String token,IreadMemcacheService ireadMemcacheService,String device_identifier){
		try {
			if(!StringUtils.isNullOrEmpty(token)){
				token=URLDecoder.decode(token,"UTF-8");
				byte[] strn=DESCoder.decrypt(DESCoder.decryptBASE64(token), IReadContent.dec_password);
				String key = new String(strn);
			//	System.out.println(key);
				String userId=key.split(":")[0];
			//	System.out.println(userId);
				if(ireadMemcacheService.getUserSignIn(userId+device_identifier)!=null){
					return userId;
				}
				
			}
		} catch (Exception e) {
			logger.error("token error");
			logger.error(token);
			e.printStackTrace();
		}
		return "";
	}
	public static String getSign(String key) throws Exception{
		byte[] sign = DESCoder.encrypt(key.getBytes(), IReadContent.dec_password);
	    String signStr = URLEncoder.encode(DESCoder.encryptBASE64(sign),"UTF-8");
	    return  signStr;
	}
	
	/**
	 * 转换手机号
	 * @Title: mobileNOConvert 
	 * @param mobiles
	 * @return   
	 * @return boolean    
	 * @throws
	 */
	public static String mobileNOConvert(String mobiles) {
		if(!StringUtils.isNullOrEmpty(mobiles)){
			Pattern p = Pattern.compile("^((13[0-9])|(15[^4,\\D])|(18[0-9]))\\d{8}$");
			Matcher m = p.matcher(mobiles);
			if(m.matches()){
				return mobiles.substring(0,mobiles.length()-(mobiles.substring(3)).length())+"****"+mobiles.substring(7);
			}
		}
		
		return mobiles;
	}
	/**
	 * 判断是否是ios设备
	 * @Title: isIOS 
	 * @param platform
	 * @return   
	 * @return boolean    
	 * @throws
	 */
	public static boolean isIOS(String platform){
		if(StringUtils.isNullOrEmpty(platform))
			return false;
		if("iOS".equals(platform)||"iOS_sdk".equals(platform)){
			return true;
		}
		return false;
		
	}
	/**
	 * 判断h5所在的设备
	 * @Title: isWEBIOS 
	 * @param user_agent
	 * @return   
	 * @return boolean    
	 * @throws
	 */
	public static boolean isWEBIOS(String user_agent){
		if(StringUtils.isNullOrEmpty(user_agent))
			return false;
		if(user_agent.toLowerCase().indexOf("iphone")>0||user_agent.toLowerCase().indexOf("ipad")>0){
			return true;
		}
		return false;
		
	}
	/**
	 * 是否是单本
	 * @Title: isSingle 
	 * @param platform
	 * @return   
	 * @return boolean    
	 * @throws
	 */
	public static boolean isSingle(String platform){
		if("android_single_yw".equals(platform)){
			return true;
		}
		if("android_single_qm".equals(platform)){
			return true;
		}
		if("android_single".equals(platform)){
			return true;
		}
		return false;
		
	}
	
	public static void governVersion(String platform,String vcode){
		

		
	}
	/**
	 * 进行sql注入处理
	 * @Title: preventInjection 
	 * @param param
	 * @return   
	 * @return String    
	 * @throws
	 */
	public static String preventInjection(String param){
		      String regex = "select|update|delete|exec|count|'|\"|=|;|>|<|%/i";
		//String regex = "/\+|\*|\`|\/|\-|\$|\#|\^|\!|\@|\%|\&|\~|\^|\[|\]|\'|\"/";
		if(!StringUtils.isNullOrEmpty(param)){
			param = param.replaceAll(regex, "");
		}
		return param;
	}
	public static void inputstreamtofile(InputStream ins,File file) {
		try {
			OutputStream os = new FileOutputStream(file);
			int bytesRead = 0;
			byte[] buffer = new byte[8192];
			while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {
				os.write(buffer, 0, bytesRead);
			}
			os.close();
			ins.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	/**
	 * 获取token中的userid，并判断是否有效
	 * @Title: getUserIdByToken 
	 * @param token
	 * @param ireadMemcacheService
	 * @return   
	 * @return String    
	 * @throws
	 *//*
	public static String getUserIdByToken(String token,IreadMemcacheService ireadMemcacheService){
		try {
			if(!StringUtils.isNullOrEmpty(token)){
				token=URLDecoder.decode(token,"UTF-8");
				String strn=RSA.decrypt(token);
				JSONObject json=JSONObject.fromObject(strn);  
				String userId=json.getString("userId");
				String device_identifier=json.getString("device_identifier");
				if(null==device_identifier){
					device_identifier="";
				}
				String sign = (String) ireadMemcacheService.getUserSignIn(userId+device_identifier);
				if(!StringUtils.isNullOrEmpty(sign)){
					String signToken = URLEncoder.encode(token,"UTF-8");
					if(signToken.equals(sign)){
						return userId;
					}
				}
			}
		} catch (Exception e) {
			logger.error("token error");
			e.printStackTrace();
		}
		return "";
	}*/
	/**
	 * 获取token中的userid，不判断是否有效
	 * @Title: getUserIdByToken 
	 * @param token
	 * @param ireadMemcacheService
	 * @return   
	 * @return String    
	 * @throws
	 *//*
	public static String getUserIdByTokenWithoutEffective(String token){
		try {
			if(!StringUtils.isNullOrEmpty(token)){
				token=URLDecoder.decode(token,"UTF-8");
				String strn=RSA.decrypt(token);
				JSONObject json=JSONObject.fromObject(strn);  
				String userId=json.getString("userId");
				return userId;
			}
		} catch (Exception e) {
			logger.error("token error");
			logger.error(token);
			e.printStackTrace();
		}
		return "";
	}*/
	
	/**
	 * 获取x位随机数
	 * @Title: getRandom 
	 * @param x
	 * @return   
	 * @return int    
	 * @throws
	 */
	public static String getRandomForSix(){
		Random rad = new Random();
		return StringUtils.getStringSix(rad.nextInt(1000000));
	}
	
	/** 
     * xml字符串转换成bean对象 
     *  
     * @param xmlStr xml字符串 
     * @param clazz 待转换的class 
     * @return 转换后的对象 
     */  
    public static Object xmlStrToBean(String xmlStr, Class<?> clazz) {  
        Object obj = null;  
        try {  
            // 将xml格式的数据转换成Map对象  
            Map<String, Object> map = xmlStrToMap(xmlStr);  
            //将map对象的数据转换成Bean对象  
            obj = mapToBean(map, clazz);  
        } catch(Exception e) {  
            e.printStackTrace();  
        }  
        return obj;  
    }  
      
    /** 
     * 将xml格式的字符串转换成Map对象 
     *  
     * @param xmlStr xml格式的字符串 
     * @return Map对象 
     * @throws Exception 异常 
     */  
    public static Map<String, Object> xmlStrToMap(String xmlStr) throws Exception {  
        if(StringUtils.isNullOrEmpty(xmlStr)) {  
            return null;  
        }  
        Map<String, Object> map = new HashMap<String, Object>();  
        //将xml格式的字符串转换成Document对象  
        Document doc = DocumentHelper.parseText(xmlStr);  
        //获取根节点  
        Element root = doc.getRootElement();  
        //获取根节点下的所有元素  
        List<?> children = root.elements();  
        //循环所有子元素  
        if(children != null && children.size() > 0) {  
            for(int i = 0; i < children.size(); i++) {  
                Element child = (Element)children.get(i);  
                map.put(child.getName(), child.getTextTrim());  
            }  
        }  
        return map;  
    }  
      
    /** 
     * 将Map对象通过反射机制转换成Bean对象 
     *  
     * @param map 存放数据的map对象 
     * @param clazz 待转换的class 
     * @return 转换后的Bean对象 
     * @throws Exception 异常 
     */  
    public static Object mapToBean(Map<String, Object> map, Class<?> clazz) throws Exception {  
        Object obj = clazz.newInstance();  
        if(map != null && map.size() > 0) {  
            for(Map.Entry<String, Object> entry : map.entrySet()) {  
                String propertyName = entry.getKey();  
                Object value = entry.getValue();  
                String setMethodName = "set"  
                        + propertyName.substring(0, 1).toUpperCase()  
                        + propertyName.substring(1);  
                Field field = getClassField(clazz, propertyName);  
                Class<?> fieldTypeClass = field.getType();  
                value = convertValType(value, fieldTypeClass);  
                clazz.getMethod(setMethodName, field.getType()).invoke(obj, value);  
            }  
        }  
        return obj;  
    }  
      
    /** 
     * 将Object类型的值，转换成bean对象属性里对应的类型值 
     *  
     * @param value Object对象值 
     * @param fieldTypeClass 属性的类型 
     * @return 转换后的值 
     */  
    private static Object convertValType(Object value, Class<?> fieldTypeClass) {  
        Object retVal = null;  
        if(Long.class.getName().equals(fieldTypeClass.getName())  
                || long.class.getName().equals(fieldTypeClass.getName())) {  
            retVal = Long.parseLong(value.toString());  
        } else if(Integer.class.getName().equals(fieldTypeClass.getName())  
                || int.class.getName().equals(fieldTypeClass.getName())) {  
            retVal = Integer.parseInt(value.toString());  
        } else if(Float.class.getName().equals(fieldTypeClass.getName())  
                || float.class.getName().equals(fieldTypeClass.getName())) {  
            retVal = Float.parseFloat(value.toString());  
        } else if(Double.class.getName().equals(fieldTypeClass.getName())  
                || double.class.getName().equals(fieldTypeClass.getName())) {  
            retVal = Double.parseDouble(value.toString());  
        } else {  
            retVal = value;  
        }  
        return retVal;  
    }  
  
    /** 
     * 获取指定字段名称查找在class中的对应的Field对象(包括查找父类) 
     *  
     * @param clazz 指定的class 
     * @param fieldName 字段名称 
     * @return Field对象 
     */  
    private static Field getClassField(Class<?> clazz, String fieldName) {  
        if( Object.class.getName().equals(clazz.getName())) {  
            return null;  
        }  
        Field []declaredFields = clazz.getDeclaredFields();  
        for (Field field : declaredFields) {  
            if (field.getName().equals(fieldName)) {  
                return field;  
            }  
        }  
  
        Class<?> superClass = clazz.getSuperclass();  
        if(superClass != null) {// 简单的递归一下  
            return getClassField(superClass, fieldName);  
        }  
        return null;  
    }   
	
	
	
	
	
	
	
	
	
	
	
	
	
	/**
	 * bean转换成json(Unicode编码)
	 * @Title: beanToJson 
	 * @param o
	 * @return   
	 * @returnType String    
	 * @throws
	 */
	public static String beanToJson(Object o){
		String str="";
		if(null==o||"".equals(o)){
			return str;
		}
		ObjectMapper objectMapper = new ObjectMapper();
		//使Jackson JSON支持Unicode编码非ASCII字符
		CustomSerializerFactory serializerFactory= new CustomSerializerFactory();
		serializerFactory.addSpecificMapping(String.class, new StringUnicodeSerializer());
		objectMapper.setSerializerFactory(serializerFactory);
		try {
			str=objectMapper.writeValueAsString(o);
		} catch (JsonGenerationException e) {
			e.printStackTrace();
		} catch (JsonMappingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		str = str.replaceAll("/", "\\\\/");
		return str;
	}

	/**
	 * 泛型排序：必须实现Comparable接口
	 * @Title: quickSort 
	 * @param in
	 * @param begin
	 * @param end   
	 * @returnType void    
	 * @throws
	 */
    @SuppressWarnings("unchecked")
    private static void quickSort(Object[] in,int begin, int end) {
        if( begin == end || begin == (end-1) ) return;
        Object p = in[begin];
        int a = begin +1;
        int b = a;
        for( ; b < end; b++) {
            //该对象类型数组必须实现Comparable接口，这样才能使用compareTo函数进行比较
            if( ((Comparable<Object>)in[b]).compareTo(p) < 0) {
                if(a == b){a++; continue;}
                Object temp = in[a];
                in[a] = in[b];
                in[b] = temp;
                a++;
            }
        }
        in[begin] = in[a-1];
        in[a-1] = p;
        if( a-1 > begin){
            quickSort(in,begin, a);
        } 
        if( end-1 > a ) {
            quickSort(in,a, end);
        } 
        return;
     }
	     
	/**
	 * 使用泛型，对任意对象数组排序，该对象类型数组必须实现Comparable接口
	 * @Title: sort 
	 * @param input   
	 * @returnType void    
	 * @throws
	 */
	public static <T extends Comparable<? super T>> void sort(T[] input){
		quickSort(input,0,input.length);
	}
	     
    /**
     * List对象进行排序的功能，参考了Java中的Java.util.Collections类的sort()函数
     * @Title: sort 
     * @param list   
     * @returnType void    
     * @throws
     */
    @SuppressWarnings("unchecked")
	public static <T > void sort(List<T> list){
        Object[] t = list.toArray();//将列表转换为数组
        quickSort(t,0,t.length); //对数组进行排序
        //数组排序完成后再写回到列表中
        ListIterator<T> i = list.listIterator();
        for (int j=0; j<t.length; j++) {
            i.next();
            i.set((T)t[j]);
        }
    }
	     
	/**
	 * int[]数组的重载函数
	 * @Title: sort 
	 * @param input   
	 * @returnType void    
	 * @throws
	 */
    public static void sort(int[] input){
        Integer[] t = new Integer[input.length];
        for(int i = 0; i < input.length; i++){
            t[i] = input[i];//封装
        }
        quickSort(t,0,t.length);//排序
        for(int i = 0; i < input.length; i++){
            input[i] = t[i];//解封装
        }
    }
	/**
	 * double[]数组的重载函数
	 * @Title: sort 
	 * @param input   
	 * @returnType void    
	 * @throws
	 */
    public static void sort(double[] input){
        Double[] t = new Double[input.length];
        for(int i = 0; i < input.length; i++){
            t[i] = input[i];
        }
        quickSort(t,0,t.length);
        for(int i = 0; i < input.length; i++){
            input[i] = t[i];
        }
    }
    /**
     * byte[]数组的重载函数
     * @Title: sort 
     * @param input   
     * @returnType void    
     * @throws
     */
    public static void sort(byte[] input){
        Byte[] t = new Byte[input.length];
        for(int i = 0; i < input.length; i++){
            t[i] = input[i];
        }
        quickSort(t,0,t.length);
        for(int i = 0; i < input.length; i++){
            input[i] = t[i];
        }
    }
    /**
     * short[]数组的重载函数
     * @Title: sort 
     * @param input   
     * @returnType void    
     * @throws
     */
    public static void sort(short[] input){
        Short[] t = new Short[input.length];
        for(int i = 0; i < input.length; i++){
            t[i] = input[i];
        }
        quickSort(t,0,t.length);
        for(int i = 0; i < input.length; i++){
            input[i] = t[i];
        }
    }
    /**
     * char[]数组的重载函数
     * @Title: sort 
     * @param input   
     * @returnType void    
     * @throws
     */
    public static void sort(char[] input){
        Character[] t = new Character[input.length];
        for(int i = 0; i < input.length; i++){
            t[i] = input[i];
        }
        quickSort(t,0,t.length);
        for(int i = 0; i < input.length; i++){
            input[i] = t[i];
        }
    }
    /**
     * float[]数组的重载函数
     * @Title: sort 
     * @param input   
     * @returnType void    
     * @throws
     */
    public static void sort(float[] input){
        Float[] t = new Float[input.length];
        for(int i = 0; i < input.length; i++){
            t[i] = input[i];
        }
        quickSort(t,0,t.length);
        for(int i = 0; i < input.length; i++){
            input[i] = t[i];
        }
    }
    
    /**
     * 使用 Map按key进行排序
     * @param map
     * @return
     */
    public static Map<String, Object> sortMapByKey(Map<String, Object> map) {
        if (map == null || map.isEmpty()) {
            return null;
        }
 
        Map<String, Object> sortMap = new TreeMap<String, Object>(
                new MapKeyComparator());
 
        sortMap.putAll(map);
 
        return sortMap;
    }

}
